#include <map>
#include <string>
#include <list>

#include "VisitorFeature.h"
#include "../../utils/BOOL.h"

VisitorFeature VisitorFeature::OutputUCase = VisitorFeature(1 << 1, make_string_ptr("OutputUCase"));
VisitorFeature VisitorFeature::OutputPrettyFormat = VisitorFeature(1 << 2, make_string_ptr("OutputPrettyFormat"));
VisitorFeature VisitorFeature::OutputParameterized = VisitorFeature(1 << 3, make_string_ptr("OutputParameterized"));
VisitorFeature VisitorFeature::OutputDesensitize = VisitorFeature(1 << 4, make_string_ptr("OutputDesensitize"));
VisitorFeature VisitorFeature::OutputUseInsertValueClauseOriginalString = VisitorFeature(1 << 5, make_string_ptr("OutputUseInsertValueClauseOriginalString"));
VisitorFeature VisitorFeature::OutputSkipSelectListCacheString = VisitorFeature(1 << 6, make_string_ptr("OutputSkipSelectListCacheString"));
VisitorFeature VisitorFeature::OutputSkipInsertColumnsString = VisitorFeature(1 << 7, make_string_ptr("OutputSkipInsertColumnsString"));
VisitorFeature VisitorFeature::OutputParameterizedQuesUnMergeInList = VisitorFeature(1 << 8, make_string_ptr("OutputParameterizedQuesUnMergeInList"));
VisitorFeature VisitorFeature::OutputParameterizedQuesUnMergeOr = VisitorFeature(1 << 9, make_string_ptr("OutputParameterizedQuesUnMergeOr"));
VisitorFeature VisitorFeature::OutputParameterizedQuesUnMergeAnd = VisitorFeature(1 << 10, make_string_ptr("OutputParameterizedQuesUnMergeAnd"));
VisitorFeature VisitorFeature::OutputParameterizedQuesUnMergeValuesList = VisitorFeature(1 << 11, make_string_ptr("OutputParameterizedQuesUnMergeValuesList"));
VisitorFeature VisitorFeature::OutputParameterizedUnMergeShardingTable = VisitorFeature(1 << 12, make_string_ptr("OutputParameterizedUnMergeShardingTable"));
VisitorFeature VisitorFeature::OutputParameterizedZeroReplaceNotUseOriginalSql = VisitorFeature(1 << 13, make_string_ptr("OutputParameterizedZeroReplaceNotUseOriginalSql"));
VisitorFeature VisitorFeature::OutputRegForPresto = VisitorFeature(1 << 14, make_string_ptr("OutputRegForPresto"));
VisitorFeature VisitorFeature::OutputKeepParenthesisWhenNotExpr = VisitorFeature(1 << 15, make_string_ptr("OutputKeepParenthesisWhenNotExpr"));
VisitorFeature VisitorFeature::OutputNameQuote = VisitorFeature(1 << 16, make_string_ptr("OutputNameQuote"));
VisitorFeature VisitorFeature::OutputDistributedLiteralInCreateTableStmt = VisitorFeature(1 << 17, make_string_ptr("OutputDistributedLiteralInCreateTableStmt"));

VisitorFeature::VisitorFeature()
{
}
VisitorFeature::VisitorFeature(uint64_t mask, string_ptr name)
{
  this->name = name;
  this->mask = mask;
}

VisitorFeature::VisitorFeature(VisitorFeature *visitor)
{
  this->name = visitor->name;
  this->mask = visitor->mask;
}
// VisitorFeature& VisitorFeature::operator=(VisitorFeature& val) {
// 		_enum = val;
// 		currstr = str.find((int)val)->second;
// 		return _enum;
// }
// VisitorFeature& VisitorFeature::operator=(VisitorFeature& val){
// 		_enum=val._enum;
// 		currstr=str.find((int)val._enum)->second;
// 		return _enum;
// }
// BOOL_ptr VisitorFeature::operator==(VisitorFeature& rgt) {
// 	return _enum==rgt._enum;
// }
// BOOL_ptr VisitorFeature::operator==(_MyEnum& rgt) {
// 	return _enum==rgt;
// }
// int VisitorFeature::value() {
// 	return (int)(_enum);
// }
// string_ptr  VisitorFeature::toString() {
// 		return currstr;
// }

u_int64_t VisitorFeature::config(int features, std::shared_ptr<VisitorFeature> feature, BOOL_ptr state)
{
  if (state)
  {
    features |= feature->mask;
  }
  else
  {
    features &= ~feature->mask;
  }

  return features;
}

u_int64_t VisitorFeature::of(std::shared_ptr<std::list<std::shared_ptr<VisitorFeature>>> features)
{
  if (features->empty())
  {
    return 0;
  }
  uint64_t v = 0;
  for (auto p1 = features->begin(); p1 != features->end(); p1++)
  {
    v |= (*p1)->mask;
  }
  return v;
}

BOOL_ptr VisitorFeature::isEnabled(int features, std::shared_ptr<VisitorFeature> feature)
{
  return ((features & feature->mask) != 0) ? BOOL::TRUE : BOOL::FALSE;
}